// 合并生产和开发配置
const path = require('path')
const EslintPackPlugin = require('eslint-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
// const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin')// 生产环境不需要hmr功能
const MiniCssExtractPlugin = require('mini-css-extract-plugin') // 提取css成单独文件
const CssMinimizerWebpackPlugin = require('css-minimizer-webpack-plugin') // css压缩
const TerserWebpackPlugin = require('terser-webpack-plugin') // js压缩
const ImageMinimizerPlugin = require('image-minimizer-webpack-plugin') // 对图片压缩
const CopyPlugin = require('copy-webpack-plugin')
const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin')

// 获取cross-env定义的环境变量
const isProduction = process.env.NODE_ENV === 'production'

// 返回处理样式loader函数
const getStyleLoaders = (pre) => {
  return [
    isProduction ? MiniCssExtractPlugin.loader : 'style-loader',
    'css-loader', {
      loader: 'postcss-loader',
      // 处理css兼容性问题
      // 配合package.json中browserslist来指定兼容性
      options: {
        postcssOptions: {
          plugins: [
            'postcss-preset-env',
          ]
        }
      }
    },
    pre && {
      loader: pre,
      options: pre === 'less-loader' ? {
        lessOptions: {
          modifyVars: { "@primary-color": "#1DA57A" },
          javascriptEnabled: true
        }
      } : {}
    }
  ].filter(Boolean)
}

module.exports = {
  entry: './src/main.js',
  output: {
    path: isProduction ? path.resolve(__dirname, "../dist") : undefined,
    filename: isProduction ? 'static/js/[name].[contenthash:10].js' : 'static/js/[name].js',
    chunkFilename: isProduction ? 'static/js/[name].[contenthash:10].chunk.js' : 'static/js/[name].chunk.js',
    assetModuleFilename: 'static/media/[hash:10][ext][query]',
    clean: true,
  },
  module: {
    rules: [
      // 处理Css
      {
        test: /\.css$/,
        use: getStyleLoaders()
      },
      {
        test: /\.less$/,
        use: getStyleLoaders("less-loader")
      },
      {
        test: /\.s[ac]ss$/,
        use: getStyleLoaders("sass-loader")
      },
      {
        test: /\.styl$/,
        use: getStyleLoaders("stylus-loader")
      },
      // 处理图片
      {
        test: /\.(jpe?g|png|gif|webp|svg)/,
        type: 'asset',
        parser: {
          dataUrlCondition: {
            maxSize: 10 * 1024,
          }
        }
      },
      // 处理其它资源
      {
        test: /\.(woff2?|ttf)/,
        type: 'asset/resource',
      },
      // 处理js
      {
        test: /\.jsx?$/,
        include: path.resolve(__dirname, '../src'),
        loader: 'babel-loader',
        options: {
          cacheDirectory: true,
          cacheCompression: false,
          plugins: [
            !isProduction && 'react-refresh/babel'
          ].filter(Boolean),// 激活js的hmr
        }
      }
    ]
  },
  // 处理html
  plugins: [
    new EslintPackPlugin({
      context: path.resolve(__dirname, '../src'),
      exclude: "node_modules",
      cache: true,
      cacheLocation: path.resolve(__dirname, '../node_modules/.cache/.eslintcache')
    }),
    new HtmlWebpackPlugin({
      template: path.resolve(__dirname, '../public/index.html'),

    }),
    !isProduction && new ReactRefreshWebpackPlugin(),// 生产环境不需要hmr功能
    isProduction && new MiniCssExtractPlugin({
      filename: 'static/css/[name].[contenthash:10].css',
      chunkFilename: 'static/css/[name].[contenthash:10].chunk.css'
    }),
    new ImageMinimizerPlugin({
      minimizer: {
        implementation: ImageMinimizerPlugin.imageminGenerate,
        options: {
          plugins: [
            ["gifsicle", { interlaced: true }],
            ["jpegtran", { progressive: true }],
            ["optipng", { optimizationLevel: 5 }],
            [
              "svgo",
              {
                plugins: [
                  "preset-default",
                  "prefixIds",
                  {
                    name: "sortAttrs",
                    params: {
                      xmlnsOrder: "alphabetical",
                    },
                  },
                ],
              },
            ],
          ],
        },
      },
    }),
    isProduction && new CopyPlugin({
      patterns: [
        {
          from: path.resolve(__dirname, '../public'),
          to: path.resolve(__dirname, '../dist'),
          globOptions: {
            // 忽略public中index.html
            ignore: ["**/index.html"],
          },
        },

      ],
    }),
  ].filter(Boolean),
  mode: isProduction ? 'production' : 'development',
  devtool: isProduction ? 'source-map' : 'cheap-module-source-map',
  optimization: {
    splitChunks: {
      chunks: "all",
      cacheGroups: {
        // react相关: react react-dom react-router-dom一起打包成一个js文件
        react: {
          test: /[\\/]node_modules[\\/]react(.*)?[\\/]/,
          name: 'chunk-react',
          priority: 40
        },
        // antd单独打包
        antd: {
          name: "chunk-antd",
          test: /[\\/]node_modules[\\/]antd(.*)/,
          priority: 30,
        },
        // 剩下的node_modules单独打包
        lib: {
          test: /[\\/]node_modules[\\/]/,
          name: 'chunk-libs',
          priority: 20
        }
      }
    },
    runtimeChunk: {
      name: entrypoint => `runtime~${entrypoint.name}.js`,
    },
    // 控制是否需要进行压缩
    minimize: isProduction,
    minimizer: [
      new CssMinimizerWebpackPlugin(),
      new TerserWebpackPlugin()
    ]
  },
  // webpack解析模块加载选项
  resolve: {
    // 自动补全文件扩展名
    extensions: ['.jsx', '.js', '.json']
  },
  devServer: {
    host: 'localhost',
    port: 3001,
    open: true,
    hot: true,// 热模块替换,
    historyApiFallback: true // 解决前端路由刷新404问题
  }
}